package com.seeyon.apps.commonExt.util;

import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormDataSubBean;
import com.seeyon.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.bean.FormTableBean;
import com.seeyon.cap4.form.exception.FormException;
import com.seeyon.cap4.form.service.CAP4FormManager;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.authenticate.domain.User;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.v3x.services.form.FormFactory;
import com.seeyon.v3x.services.form.bean.*;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.logging.LogFactory;

import java.math.BigDecimal;
import java.util.*;

/**
 * 用于存储到底表中--也可以封装成Http接口
 *
 * @author Administrator
 * @author 2020年5月22日
 */
public class SaveToUnFlowUtilExt {

    private static org.apache.commons.logging.Log logger = LogFactory.getLog(SaveToUnFlowUtilExt.class);

    private static FormBean form;
    private static FormFactory formFactory;
    private static CAP4FormManager cap4FormManager = (CAP4FormManager) AppContext.getBean("cap4FormManager");

    /**
     * @return formFactory
     */
    public FormFactory getFormFactory() {
        return formFactory;
    }

    /**
     * @param formFactory 要设置的 formFactory
     */
    public void setFormFactory(FormFactory formFactory) {
        this.formFactory = formFactory;
    }

    public void setCap4FormManager(CAP4FormManager cap4FormManager) {
        this.cap4FormManager = cap4FormManager;
    }

    public static FormBean getForm(String code) throws BusinessException {
        form = cap4FormManager.getFormByFormCode(code);
        return form;
    }





    public static Long saveOrUpdateFormDataWithValid(String senderName, String formCode, String[] valiFieldAry, Map<String, Object> formParams) throws BusinessException {
        if (null == senderName) {
            senderName = Optional.ofNullable(AppContext.getCurrentUser()).map(User::getLoginName).orElseThrow(() -> new FormException("保存表单数据异常：请传入操作人工号!"));
        }
        Map<String, Object> masterParams = new HashMap<>();
        Map<String, Object> subParams = new HashMap<>();
        for (Map.Entry<String, Object> entry : formParams.entrySet()) {
            if (entry.getValue() instanceof Collection) {
                subParams.put(entry.getKey(), entry.getValue());
            }else {
                masterParams.put(entry.getKey(), entry.getValue());
            }
        }
        FormBean formBean =  getForm(formCode);
        Assert.notNull(formBean, "表单编号【{}】不存在", formCode);

        try {
            FormExport formExport = new FormExport();
            formExport.setFormId(new BigDecimal(0).longValue());
            formExport.setFormName((String) formBean.getAllTableName().get(0));
            List<DefinitionExport> definitions = new ArrayList<>();
            List<ValueExport> values = new ArrayList<>();
            List<DefinitionExport> subDefinitions = new ArrayList<DefinitionExport>(); // 从表的字段定义

            List<FormFieldBean> filedBeans = formBean.getAllFieldBeans();
            for (FormFieldBean fieldBean : filedBeans) {
                if (fieldBean.isMasterField()) {
                    DefinitionExport defExp = new DefinitionExport();
                    defExp.setName(fieldBean.getName());
                    defExp.setType(getIntType(fieldBean.getFieldType()));
                    defExp.setDisplayName(fieldBean.getDisplay());
                    if (fieldBean.isNull()) {
                        defExp.setIsNullable(1);
                    } else {
                        defExp.setIsNullable(0);
                    }
                    defExp.setLen(Integer.parseInt(fieldBean.getFieldLength()));
                    definitions.add(defExp);
                    ValueExport valExp = new ValueExport();
                    valExp.setDisplayName(fieldBean.getDisplay());
                    String value = masterParams.get(fieldBean.getDisplay()) == null ? "" : masterParams.get(fieldBean.getDisplay()).toString();
                    valExp.setValue(value);
                    valExp.setDisplayValue(null);
                    values.add(valExp);
                }
                if (fieldBean.isSubField()) {
                    DefinitionExport subExp = new DefinitionExport();
                    subExp.setName(fieldBean.getName());
                    subExp.setType(getIntType(fieldBean.getFieldType()));
                    subExp.setDisplayName(fieldBean.getDisplay());
                    if (fieldBean.isNull()) {
                        subExp.setIsNullable(1);
                    } else {
                        subExp.setIsNullable(0);
                    }
                    subExp.setLen(Integer.parseInt(fieldBean.getFieldLength()));
                    subDefinitions.add(subExp);
                }
            }

            //插入重复表数据
            List<SubordinateFormExport> subordinateForms = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(subDefinitions) && MapUtil.isNotEmpty(subParams)) {
                for (Map.Entry<String, Object> subEntry : subParams.entrySet()) {

                    FormTableBean tableBean = formBean.getSubTableBean().stream()
                            .filter(item -> item.getDisplay().equals(subEntry.getKey()))
                            .findFirst()
                            .orElse(null);
                    if (null == tableBean) {
                        continue;
                    }
                    List<Map<String,Object>> dtlDatas = (List<Map<String, Object>>) subEntry.getValue();
                    SubordinateFormExport subDfe = new SubordinateFormExport();
                    List<RecordExport> subValues = new ArrayList<>(); // 从表的字段记录

                    for (Map<String, Object> dtlData : dtlDatas) {
                        List<ValueExport> subvalue = new ArrayList<>();
                        RecordExport reExp = new RecordExport();
                        for (Map.Entry<String, Object> fieldDataEntry : dtlData.entrySet()) {
                            FormFieldBean fieldBeanByDisplay = tableBean.getFieldBeanByDisplay(fieldDataEntry.getKey());
                            if (null == fieldBeanByDisplay) {
                                continue;
                            }
                            ValueExport valExp = new ValueExport();
                            valExp.setDisplayName(fieldDataEntry.getKey());
                            String value = String.valueOf(fieldDataEntry.getValue());
                            valExp.setValue(value);
                            valExp.setDisplayValue(null);
                            subvalue.add(valExp);
                        }
                        reExp.setRecord(subvalue);
                        subValues.add(reExp);
                    }
                    subDfe.setValues(subValues);
                    subordinateForms.add(subDfe);
                }
                //保存重复表数值
                formExport.setSubordinateForms(subordinateForms);
            }
            //保存主表数值
            formExport.setDefinitions(definitions);
            formExport.setValues(values);

            if (formFactory == null) {
                formFactory = (FormFactory) AppContext.getBean("formFactory");
            }
            Map<String, Object> relevantParam = new HashMap<>();
            return formFactory.importBusinessForm(senderName, formCode, formExport, valiFieldAry, relevantParam);
        } catch (Exception e) {
            logger.info("保存到底表报错", e);
            throw new FormException(e.getMessage());
        }
    }

    private static int getIntType(String type) {
        int intType = 0;
        type = type.toUpperCase();
        if (type.equals("VARCHAR")) {
            intType = 0;
        }
        if (type.equals("LONGTEXT")) {
            intType = 1;
        }
        if (type.equals("DATETIME")) {
            intType = 2;
        }
        if (type.equals("TIMESTAMP")) {
            intType = 3;
        }

        if (type.equals("DECIMAL")) {
            intType = 4;
        }
        if (type.equals("HANDWRITE")) {
            intType = 5;
        }
        return intType;
    }

    private static void combineSub(boolean fillNull, Map<String, Object> dtlData, FormDataSubBean formDataSubBean, List<FormDataSubBean> subDatas) {
        for (Map.Entry<String, Object> subFieldDataEntry : dtlData.entrySet()) {
            FormFieldBean subFormFieldBean = formDataSubBean.getFormTable().getFieldBeanByDisplay(subFieldDataEntry.getKey());
            if (null == subFormFieldBean) {
                continue;
            }
            if (!fillNull && null == subFieldDataEntry.getValue()) {
                continue;
            }
            formDataSubBean.addFieldValue(subFormFieldBean.getName(), subFieldDataEntry.getValue());
        }
        if (null == subDatas) {
            return;
        }
        subDatas.add(formDataSubBean);
    }

}
